#!/usr/bin/env perl
#
# Copyright (c) 2012-2013 Jeffrey M. Squyres.  All rights reserved.
#
# $COPYRIGHT$
# 
# Additional copyrights may follow
# 
# $HEADER$
#

###########################################################################
# THIS IS INCOMPLETE / DOESN'T WORK.  Just committing what I have so far...
###########################################################################

package RubySlippers::Query::sosumi;

use strict;
use RubySlippers::Messages;
use RubySlippers::Util;
use threads;
use threads::shared;


# Local state
my $_tid;
my $_sosumi_thread_time_to_die;
share($_sosumi_thread_time_to_die);
my %_thread_results;
share(%_thread_results);

# Values filled in from the main configuration
my $_icloud_username;
my $_icloud_password;
my $_sosumi_exec;
my $_analysis_filename;
my $_frequency = 15 * 60;
my $_frequency_str;


sub _query_fmip {
    # JMS Continue here.  Query the FMiP service and return results in
    # a hash or something.  Return undef if unable to query.
}

sub _sosumi_thread_main {
    Debug("Sosumi thread starting");

    # Output the output file for writing (if defined)
    if (defined($_analysis_filename)) {
        open(OUT, ">>$_analysis_filename") || 
            die "Can't open $_analysis_filename for writing";
    }

    # Main thread loop.  We actually wake up frequently so that we can
    # check to see if it's time to die.  But even though we wake up
    # often, we only invoke sosumi once every $_frequency seconds.
    my $next_wakeup = time() + $_frequency;
    while (! $_sosumi_thread_time_to_die) {
        # Is it time to invoke sosumi?
        if (time() >= $next_wakeup) {
            # Yes!
            lock(%_thread_results);

            # Query the FMiP service; save the results into
            # %_thread_results so that the main thread will see them.
            my $results = _query_fmip();

            # JMS Continue here -- write results into
            # %_thread_results.

            # Set our next wakeup time
            $next_wakeup = time() + $_frequency;
        } else {
            # No.  Just sleep for a second before we check everything
            # again.
            sleep(1);
        }
    }

    close(OUT);

    Debug("Sosumi thread finished");
    threads->exit(0);
}

sub _sosumi_query {
    lock(%_thread_results);

    # Has the thread seen anything in the last time interval?
    my @k = sort(keys(%_thread_results));
    return
        if ($#k < 0);

    # JMS For now, just return
    return;

    # JMS Continue here -- pass the found info on to Decide
    my $decision_args = {
        query => "sosumi",
        sosumi_cool_info => "whatever_you_found",
    };
    RubySlippers::Engine::Decide($decision_args);
}


# Shut down at the end of the run
sub _sosumi_close {
    # Tell the thread to quit, then wait for it to die (may take a
    # minute because it might be in the middle of a query).
    $_sosumi_thread_time_to_die = 1;
    if (defined($_tid)) {
        $_tid->join();
        $_tid = undef;
    }
}

sub open {
    # Get the mandatory sosumi parameters
    $_icloud_username = RubySlippers::Config::get("sosumi_icloud_username");
    $_icloud_password = RubySlippers::Config::get("sosumi_icloud_password");

    # If no icloud username/password, then just return silently
    if (!defined($_icloud_username) && !defined($_icloud_password)) {
        return undef;
    }
    if (defined($_icloud_username) || defined($_icloud_password)) {
        Warning("Sosumi: You must provide both an iCloud username *and* password if you want to use the Sosumi query plugin");
        return undef;
    }

    # Optional analysis filename parameter
    $_analysis_filename = 
        RubySlippers::Config::get("sosumi_analysis_filename");

    # Get the polling frequency
    my $tmp =
        RubySlippers::Config::parse_config_time("sosumi_poll_frequency",
                                                $_frequency);
    $_frequency = $tmp;
        if (defined($tmp));
    $_frequency_str = RubySlippers::Config::make_time_str($_frequency);

    # Find sosumi.php
    # JMS Fixme -- the name need not be sosumi.php.  Carl provided
    # sosumi-timeaway.php, for example.
    $_sosumi_exec = RubySlippers::Config::get("sosumi_bin");
    $_sosumi_exec = RubySlippers::Util::path_find("sosumi.php")
        if (!defined($_sosumi_exec));
    if (!defined($_sosumi_exec) || ! -x $_sosumi_exec) {
        Verbose("Did not find sosumi.php; skipping the Sosumi module");
        return undef;
    }

    Debug("Sosumi found $_sosumi_exec");

    # Get the current status from FMiP so that a) we can ensure it
    # works, and b) we can get a list of devices.
    my $result = _query_fmip();
    if (!defined($result)) {
        Verbose("Unable to query the Find my iPhone service; skipping the sosumi plugin");
        return undef;
    }

    # Create the thread to query FMiP in the background.
    $_tid = threads->create(\&_sosumi_thread_main, $i);
    if (!defined($_tid)) {
        Warning("Failed to create sosumi polling thread");
        exit(1);
    }

    # Create an array of one module to return
    Verbose("sosumi: Creating a query module");
    my @ret;
    push(@ret, {
        frequency => 10,
        callback => \&_sosumi_query,
        close => \&_sosumi_close,
        name => "Sosumi query",
         });
    return \@ret;
}

1;
